﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Navigant.Web.UI
{
    public class PagedList<T> : List<T>, IPagedList
    {
        #region Private Fields

        private int totalCount;
        private int pageIndex;
        private int pageSize;

        #endregion

        #region Constructors

        public PagedList(IList<T> source, int index, int pageSize, int totalCount) 
            : this(source, index, pageSize, totalCount, false)
        {
        }

        public PagedList(IList<T> source, int index, int pageSize, 
            int totalCount, bool serverSidePaging)
        {
            this.totalCount = totalCount;
            this.pageSize = pageSize;
            this.pageIndex = index;
            if (serverSidePaging)
            {
                this.AddRange(source);
            }
            else
            {
                this.AddRange(this.Take(this.Skip(source, (index * pageSize)), pageSize));
            }
        }

        #endregion

        #region Private Methods

        private IEnumerable<T> Take(IEnumerable<T> source, int count) 
        { 
            if (count > 0) 
            { 
                foreach (T element in source) 
                { 
                    yield return element; 
                    if (--count == 0) break; 
                } 
            } 
        }

        private IEnumerable<T> Skip(IEnumerable<T> source, int count) 
        { 
            using (IEnumerator<T> e = source.GetEnumerator()) 
            {
                while (count > 0 && e.MoveNext()) count--;
                if (count <= 0) 
                {
                    while (e.MoveNext())
                    {
                        yield return e.Current;
                    }
                } 
            }
        }

        #endregion

        #region IPagedList Members

        public int TotalCount
        {
            get
            {
                return this.totalCount;
            }
        }

        public int PageIndex
        {
            get
            {
                return this.pageIndex;
            }
        }

        public int PageSize
        {
            get
            {
                return this.pageSize;
            }
        }

        public bool HasPreviousPage
        {
            get { return (this.pageIndex > 0); }
        }

        public bool HasNextPage
        {
            get { return ((this.pageIndex + 1) * this.pageSize) < this.totalCount; }
        }

        #endregion
    }
}
